<?php

namespace app\admin\model;

use think\Model;
use app\admin\service\Warehouse as WarehouseService;

class Inventory extends BaseModel
{
    protected $warehouse = [];
    protected $attributes = [
        'pay_status' => [
            1 => '未支付',
            2 => '待审核',
            3 => '已支付',
            4 => '部分支付'
        ],
        'is_futures' => [
            0 => '现货',
            1 => '在途期货',
            2 => '大期货'
        ],
        'source_table' => [
            'inventory' => '库存',
            'purchase_orders' => '采购'
        ],
        'is_sale' => [
            0 => '否',
            1 => '是'
        ],
        'allow_zero_stock_sale' => [  // 是否允许零库存销售
            0 => '不允许',
            1 => '允许'
        ]
    ];

    protected $enumCallbacks = [
        'warehouse' => 'getFirstWarehouseEnum',
        'wid' => 'getWarehouseEnum',
        'brand' => 'getBrandEnum',
        'currency' => 'getCurrencyEnum',
        'warehouse_parent_tree' => 'getWarehouseParentTreeEnum'
    ];

    // 设置字段信息
    protected $schema = [
        'id' => 'int',
        'productid' => 'int',
        'wid' => 'string',
        'source_table' => 'string', // 数据来源表名
        'source_id' => 'int', // 数据来源表ID
        'initial_qty' => 'int', //初始库存数据，在入库或者转入时写入，后续全程不变
        'convertible_qty' => 'int', // 期货可转数量，在入库或者转入时写入，后续转出时扣减
        'available_qty' => 'int', // 可用库存数量，在入库或者转入时写入，订单支付时扣减
        'lock_qty' => 'int', // 锁定库存数量，订单转换时写入锁定数量，锁定库存不可售
        'arrival_date' => 'date', // 到货日期 期货必填，现货为null
        'real_arrival_date' => 'date', // 真实到货日期
        'inbound_batch' => 'string', // 入库批次，自动生成 （采购订单编码 + 自增数）例：2024091166e14f5d6623b_1
        'is_futures' => 'int', // 库存类型  0-现货 1-在途期货 2-大期货
        'remark' => 'string',
        'last_audit_date' => 'datetime',
        'is_del' => 'int',
        'creator' => 'int',
        'create_time' => 'datetime',
        'update_time' => 'datetime',
        'updater' => 'int',
        'is_sale' => 'int',
        'allow_zero_stock_sale' => 'int',
        'purchase_currency' => 'int',
        'purchase_price' => 'decimal',
        'if_tlz' => 'int',
        'ccname_ids' => 'string'
    ];

    public function getFirstWarehouseEnum()
    {
        return Warehouse::where('is_del', 0)->where('status', 1)->whereNull('fl_warehouse_id')->column('id as value,name as label');
    }

    public function getWarehouseParentTreeEnum()
    {
        return $this->parentTree($this->getWarehouseData(),null);
    }

    public function getWarehouseData()
    {
        if(!$this->warehouse){
            $this->warehouse =  Warehouse::where('is_del', 0)->where('status', 1)->column('id as value,name as label,fl_warehouse_id,fl_warehouse_id as parent_id');
        }
        return $this->warehouse;
    }

    public function getWarehouseEnum()
    {
        return $this->getWarehouseData();
    }

    public function getBrandEnum()
    {
        return ProductBrand::where('is_del', 0)->column('id as value,name as label');
    }

    public function getCurrencyEnum()
    {
        return TransactionCurrency::where('is_del', 0)->column('id as value,name as label');
    }

    public static function getStaticEnum()
    {
        return [
            'pay_status' => [
                1 => '未支付',
                2 => '待审核',
                3 => '已支付',
                4 => '部分支付'
            ],
            'is_futures' => [
                0 => '现货',
                1 => '在途期货',
                2 => '大期货'
            ],
            'source_table' => [
                'inventory' => '库存',
                'purchase_orders' => '采购'
            ],
            'is_sale' => [
                0 => '否',
                1 => '是'
            ],
            'is_futures_text' => [
                '现货' => 0,
                '在途期货' => 1,
                '大期货' => 2
            ]
        ];
    }

    public function getCname()
    {
        return $this->getProduct()->bind(['cname', 'sku', 'code','hashrate','cost']);
    }

    public function getConditionTextAttr($value, $data)
    {
        return $data['condition'] == 1 ? '是' : '否';
    }

    public function getIsAdvanceTextAttr($value, $data)
    {
        return $data['is_advance'] == 1 ? '是' : '否';
    }

    public function getIsFuturesTextAttr($value, $data)
    {
        return $data['is_futures'] == 1 ? '是' : '否';
    }

    public function creator()
    {
        return $this->getOperator()->bind(['nickname']);
    }

    public function getOperator()
    {
        return $this->hasOne(Operator::class, 'id', 'creator');
    }

    public function getProduct()
    {
        return $this->hasOne(Product::class, 'id', 'productid');
    }

    /* 仓库名称 */
    public function warehouse()
    {
        return $this->hasOne('Warehouse', 'id', 'wid');
    }

    public function getWarehouseName()
    {
        return $this->warehouse()->bind(['warehouse_name' => 'name']);
    }
    public function getWarehouseNames()
    {
        // 1. 获取逗号分隔的wid字符串
        $widStr = $this->wid;

        // 2. 安全分割为数组（兼容空值和空格）
        $widArray = array_filter(
            array_map('intval', preg_split('/\s*,\s*/', trim($widStr))),
            function($wid) { return $wid > 0; }
        );

        if (empty($widArray)) {
            return '';
        }

        // 3. 批量查询仓库名称（避免N+1问题）
        $warehouses = Warehouse::whereIn('id', $widArray)
            ->column('name', 'id');

        // 4. 按原始顺序组合名称
        $names = [];
        foreach ($widArray as $wid) {
            if (isset($warehouses[$wid])) {
                $names[] = $warehouses[$wid];
            }
        }

        return implode(', ', $names);
    }
    /* 商品 */
    public function product()
    {
        return $this->hasOne('Product', 'id', 'productid');
    }

    public function item()
    {
        return $this->hasOne('Product', 'id', 'productid');
    }


    public function brands()
    {
        return $this->hasOne('ProductBrand', 'id', 'brand');
    }

    /**
     *  折扣阶梯价
     */
    public function discount()
    {
        return $this->hasMany('ProductDiscount', 'inventoryid', 'id')->field(['level', 'num', 'rate', 'inventoryid', 'price as sales_price']);
    }

    public function brandName()
    {
        return $this->hasOne(Product::class, 'id', 'productid')->with('getBrandValue');
    }

    public function categoryName()
    {
        return $this->hasOne(Product::class, 'id', 'productid')->with('getBrandValue');
    }

    public function getIsFuturesValueAttr($value, $data)
    {
        return isset($this->attributes['is_futures'][$data['is_futures']]) ? $this->attributes['is_futures'][$data['is_futures']] : '';
    }

    public function getActualPriceAttr($value, $data)
    {
        return $data['sales_price'];
    }

    public function productPrice()
    {
        return $this->hasOne(ProductPrice::class, 'inventory_id', 'id')->where('is_del', 0)->with('discount');
    }

    public function productPrices()
    {
        return $this->hasMany(ProductPrice::class, 'inventory_id', 'id')->where('is_del', 0)->with(['discount', 'currency']);
    }

    public function normalOrder()
    {
        return $this->hasMany(OrderItem::class, 'inventory_id', 'id');
    }

    public function wholesalOrder()
    {
        return $this->hasMany(WholesalOrderItem::class, 'inventory_id', 'id');
    }

    public function receipt(){
        return $this->hasOne(PurchaseReceiptDetails::class, 'inventory_id', 'id')->with('orders_detail');
    }

    public function getWarehouseValueAttr($value, $data)
    {
        if (is_null($data['wid']) || '' == $data['wid']) {
            return '';
        }
        $warehouseIds = explode(',', $data['wid']);

        $partners = Warehouse::whereIn('id', $warehouseIds)->field('name')->select()->toArray();

        return  implode(',', array_column($partners, 'name'));
    }

    public function getFieldEnum($field)
    {
        return $this->getEnum($field, [], 'label');
    }


    /**
     *  菜单递归处理
     */
    /**
     *  菜单递归处理
     */
    public function parentTree(array $data, $parent_id = 0) {
        $branch = [];
        foreach ($data as $value) {
            $element = [];
            $element['value'] = $value['value'];
            $element['label'] = $value['label'];
            if ($value['parent_id'] == $parent_id) {
                $children = $this->parentTree($data, $value['value']);
                if ($children) {
                    $element['children'] = $children;
                }
                $branch[] = $element;
            }
        }
        return $branch;
    }

    public static function getInventoryInfoByFourElements($arrival_date, $wid, $is_futures, $productId)
    {
        $inventoryInfo = self::alias('inventory')->where([
            'inventory.arrival_date' => $arrival_date,
            'inventory.productid' => $productId,
            'inventory.is_del' => 0
        ])->where(function ($query) use ($wid, $is_futures) {
            if (2 == $is_futures) {
                $query->whereRaw('FIND_IN_SET(? , inventory.wid) > 0', [$wid]);
            } else {
                $query->where('inventory.wid', $wid);
            }
        })->join('product_price', 'inventory.id = product_price.inventory_id')->field('inventory.*')
            ->order('inventory.id desc')
            ->find()
            ->toArray();

        return $inventoryInfo;
    }
}
